#include <iostream>
#include <stdlib.h>
#include <string.h>
#include "warpUtil.h"
#include "warpsol.h"

int main(int argc, char **argv) {
  int retval=-1;
  warputil W;
  enum { COMPRESS, UNCOMPRESS, NOTSET } mode = NOTSET;
  if(! strcmp(argv[0], "sol2jpc") ) mode = COMPRESS;
  if(! strcmp(argv[0], "jpc2sol") ) mode = UNCOMPRESS;
  string rate="1";
  string tile="";
  int nproc = 1;
  bool coward       = true;
  bool continuation = false;
  bool recursive = false;
  bool preserve = false;
  bool robust = false;
  int opt;

  while(( opt = getopt(argc, argv, "acCuoiDr:p:t:")) != -1) { 
    switch(opt) {
    case 'c': 
      mode  = COMPRESS; 
      break;

    case 'C': 
      continuation  = true; 
      break;


    case 'u': 
      mode  = UNCOMPRESS; 
      break;

    case 'a': 
      preserve  = true; 
      break;

    case 'r': 
      rate  = optarg; 
      break;

    case 't': 
      tile  = optarg; 
      break;


    case 'D':
      recursive = true;
      break;

    case 'i':
      robust = true;
      break;



    case 'o': 
      coward = false;
      break;

#if defined  HAVE_THREADS || defined USE_FORK
   case 'p': 
      nproc = atoi(optarg); 
      break;
#endif

    default: 
      goto USAGE;
    }
  }


  if(argc - optind < 2) goto USAGE;

  if(NOTSET == mode) {
    std::cerr << "You must select either compress [-c] or uncompress [-u] mode" << std::endl;
    exit(EXIT_FAILURE);
  }

  if(continuation && !coward) {
    std::cerr << "Options -o and -C are mutually exclusive" << std::endl;
    exit(EXIT_FAILURE);
  }


  W.rate(rate);
  W.coward(coward);
  W.preserveAP(preserve);
  W.robust(robust);
  W.continuation(continuation);
  W.tilesize(tile);
#if defined HAVE_THREADS || defined USE_FORK
  W.nProcessor(nproc);
#endif


  if(!recursive) {
    warpSol warp;
    string infile = argv[optind];
    string outfile = argv[optind + 1];
    retval = (COMPRESS == mode) 
           ? W.compressFile(infile, outfile, warp) 
           : W.unCompressFile(infile, outfile, warp);
  } else {
    string sdir = argv[optind];
    string tdir = argv[optind + 1];
    retval =  W.processDirs(sdir, tdir, COMPRESS == mode);
  }
  exit(retval); 

  USAGE:
    std::cerr << "Usage: " << argv[0] << " [options]  ( (infile outfile) |  (indirectory|outdirectory))" << std::endl;  
    std::cerr << "       -a: preserve access times and permissions" << std::endl;
    std::cerr << "       -C: continue a previously aborted run (do not overwrite existing target files, but continue)" << std::endl;
    std::cerr << "       -c: compress  tiff image to jpeg2000" << std::endl;
    std::cerr << "       -D: operate on directories, compress all files in the directory" << std::endl;
    std::cerr << "       -i: continue after errors in a single files (only -D)" << std::endl;
    std::cerr << "       -o: write to output file even if file already exists" << std::endl;
#if defined HAVE_THREADS || defined USE_FORK
    std::cerr << "       -p n: set number of threads to use" << std::endl;
#endif 
    std::cerr << "       -r: set compression rate [default: 1] (Compression mode only)" << std::endl;
    std::cerr << "       -t: set tile-size [default: 128] (Compression mode only)" << std::endl;
    std::cerr << "       -u: uncompress jpeg2000 to tiff image" << std::endl;
   exit(EXIT_FAILURE);
}

